﻿using System.Linq.Expressions;
using Common.Autofac;
using Common.Dto;
using Microsoft.EntityFrameworkCore;
using Common.Extensions;

namespace Common.Abstraction;

// TODO 完善方法
/// <summary>
/// 仓储基类
/// </summary>
/// <typeparam name="T"></typeparam>
/// <typeparam name="TContext"></typeparam>
/// <typeparam name="TIdType"></typeparam>
public abstract class RepositoryBase<T, TContext, TIdType>
    where T : class
    where TContext : DbContext
{
    [Autowired] public TContext DbContext { get; set; }


    public List<T> FindAll()
    {
        return DbContext.Set<T>().AsNoTracking().ToList();
    }

    public async Task<PageObject<T>> FindPagedListAsync(PageQuery pageQuery,
        SortObject sortObject,
        params Expression<Func<T, bool>>[] predicate)
    {
        var pageNo = pageQuery.PageNo ?? 1;
        if (pageNo < 1)
        {
            pageNo = 1;
        }

        var pageSize = pageQuery.PageSize ?? 10;
        if (pageSize < 1) pageSize = 1;
        IQueryable<T> queryable = DbContext.Set<T>();
        queryable = predicate.Aggregate(queryable, (current, expression) => current.Where(expression));

        var total = await queryable.CountAsync();

        var isDesc = sortObject.Direction.Equals(SortDirection.Desc);
        queryable = queryable.OrderBy(sortObject.Field, isDesc);

        var list = await queryable.Skip(pageNo - 1).Take(pageSize).ToListAsync();

        return new PageObject<T>() { Total = total, List = list };
    }

    public async Task<List<T>> FindAllAsync()
    {
        return await DbContext.Set<T>().ToListAsync();
    }

    public T? FindById(TIdType id)
    {
        return DbContext.Set<T>().Find(id);
    }

    public async Task<T> SaveAsync(T entity)
    {
        await DbContext.Set<T>().AddAsync(entity);
        await DbContext.SaveChangesAsync();
        return entity;
    }

    public void Save(T entity)
    {
        DbContext.Set<T>().Add(entity);
        DbContext.SaveChanges();
    }
}